home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
objfnt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
36KB
|
1,770 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* objfnt -
* Support for spline and polygonal fonts.
*
* Paul Haeberli - 1990
*/
#include "stdio.h"
#include "gl.h"
#include "objfnt.h"
#include "resource.h"
static poly_print();
static spline_print();
static drawcurve();
static bezadapt();
/* the following characters are used by the SEAC command to make */
/* accented (composite) characters in text fonts */
pschar accentlist[NACCENT] = {
"/grave", 0301, 0,
"/acute", 0302, 0,
"/circumflex", 0303, 0,
"/tilde", 0304, 0,
"/macron", 0305, 0,
"/breve", 0306, 0,
"/dotaccent", 0307, 0,
"/dieresis", 0310, 0,
"/ring", 0312, 0,
"/cedilla", 0313, 0,
"/hungarumlaut", 0315, 0,
"/ogonek", 0316, 0,
"/caron", 0317, 0,
"/dotlessi", 0365, 0
};
pschar charlist[NASCII] = {
"/space", 040, 0,
"/exclam", 041, 0,
"/quotedbl", 042, 0,
"/numbersign", 043, 0,
"/dollar", 044, 0,
"/percent", 045, 0,
"/ampersand", 046, 0,
"/quoteright", 047, 0,
"/parenleft", 050, 0,
"/parenright", 051, 0,
"/asterisk", 052, 0,
"/plus", 053, 0,
"/comma", 054, 0,
"/hyphen", 055, 0,
"/period", 056, 0,
"/slash", 057, 0,
"/zero", 060, 0,
"/one", 061, 0,
"/two", 062, 0,
"/three", 063, 0,
"/four", 064, 0,
"/five", 065, 0,
"/six", 066, 0,
"/seven", 067, 0,
"/eight", 070, 0,
"/nine", 071, 0,
"/colon", 072, 0,
"/semicolon", 073, 0,
"/less", 074, 0,
"/equal", 075, 0,
"/greater", 076, 0,
"/question", 077, 0,
"/at", 0100, 0,
"/A", 0101, 0,
"/B", 0102, 0,
"/C", 0103, 0,
"/D", 0104, 0,
"/E", 0105, 0,
"/F", 0106, 0,
"/G", 0107, 0,
"/H", 0110, 0,
"/I", 0111, 0,
"/J", 0112, 0,
"/K", 0113, 0,
"/L", 0114, 0,
"/M", 0115, 0,
"/N", 0116, 0,
"/O", 0117, 0,
"/P", 0120, 0,
"/Q", 0121, 0,
"/R", 0122, 0,
"/S", 0123, 0,
"/T", 0124, 0,
"/U", 0125, 0,
"/V", 0126, 0,
"/W", 0127, 0,
"/X", 0130, 0,
"/Y", 0131, 0,
"/Z", 0132, 0,
"/bracketleft", 0133, 0,
"/backslash", 0134, 0,
"/bracketright", 0135, 0,
"/asciicircum", 0136, 0,
"/underscore", 0137, 0,
"/quoteleft", 0140, 0,
"/a", 0141, 0,
"/b", 0142, 0,
"/c", 0143, 0,
"/d", 0144, 0,
"/e", 0145, 0,
"/f", 0146, 0,
"/g", 0147, 0,
"/h", 0150, 0,
"/i", 0151, 0,
"/j", 0152, 0,
"/k", 0153, 0,
"/l", 0154, 0,
"/m", 0155, 0,
"/n", 0156, 0,
"/o", 0157, 0,
"/p", 0160, 0,
"/q", 0161, 0,
"/r", 0162, 0,
"/s", 0163, 0,
"/t", 0164, 0,
"/u", 0165, 0,
"/v", 0166, 0,
"/w", 0167, 0,
"/x", 0170, 0,
"/y", 0171, 0,
"/z", 0172, 0,
"/braceleft", 0173, 0,
"/bar", 0174, 0,
"/braceright", 0175, 0,
"/asciitilde", 0176, 0,
NULL, 0177, 0,
NULL, 0200, 0,
NULL, 0201, 0,
NULL, 0202, 0,
NULL, 0203, 0,
NULL, 0204, 0,
NULL, 0205, 0,
NULL, 0206, 0,
NULL, 0207, 0,
NULL, 0210, 0,
NULL, 0211, 0,
NULL, 0212, 0,
NULL, 0213, 0,
NULL, 0214, 0,
NULL, 0215, 0,
NULL, 0216, 0,
NULL, 0217, 0,
NULL, 0220, 0,
NULL, 0221, 0,
NULL, 0222, 0,
NULL, 0223, 0,
NULL, 0224, 0,
NULL, 0225, 0,
NULL, 0226, 0,
NULL, 0227, 0,
NULL, 0230, 0,
NULL, 0231, 0,
NULL, 0232, 0,
NULL, 0233, 0,
NULL, 0234, 0,
NULL, 0235, 0,
NULL, 0236, 0,
NULL, 0237, 0,
NULL, 0240, 0,
"/exclamdown", 0241, 0,
"/cent", 0242, 0,
"/sterling", 0243, 0,
"/currency", 0244, 0,
"/yen", 0245, 0,
"/brokenbar", 0246, 0,
"/section", 0247, 0,
"/dieresis", 0250, 0,
"/copyright", 0251, 0,
"/ordfeminine", 0252, 0,
"/guillemotleft", 0253, 0,
"/logicalnot", 0254, 0,
"/hyphen", 0255, 0,
"/registered", 0256, 0,
"/macron", 0257, 0,
"/degree", 0260, 0,
"/plusminus", 0261, 0,
"/twosuperior", 0262, 0,
"/threesuperior", 0263, 0,
"/acute", 0264, 0,
"/mu", 0265, 0,
"/paragraph", 0266, 0,
"/periodcentered", 0267, 0,
"/cedilla", 0270, 0,
"/onesuperior", 0271, 0,
"/ordmasculine", 0272, 0,
"/guillemotright", 0273, 0,
"/onequarter", 0274, 0,
"/onehalf", 0275, 0,
"/threequarters", 0276, 0,
"/questiondown", 0277, 0,
"/Agrave", 0300, 0,
"/Aacute", 0301, 0,
"/Acircumflex", 0302, 0,
"/Atilde", 0303, 0,
"/Adieresis", 0304, 0,
"/Aring", 0305, 0,
"/AE", 0306, 0,
"/Ccedilla", 0307, 0,
"/Egrave", 0310, 0,
"/Eacute", 0311, 0,
"/Ecircumflex", 0312, 0,
"/Edieresis", 0313, 0,
"/Igrave", 0314, 0,
"/Iacute", 0315, 0,
"/Icircumflex", 0316, 0,
"/Idieresis", 0317, 0,
"/Eth", 0320, 0,
"/Ntilde", 0321, 0,
"/Ograve", 0322, 0,
"/Oacute", 0323, 0,
"/Ocircumflex", 0324, 0,
"/Otilde", 0325, 0,
"/Odieresis", 0326, 0,
"/multiply", 0327, 0,
"/Oslash", 0330, 0,
"/Ugrave", 0331, 0,
"/Uacute", 0332, 0,
"/Ucircumflex", 0333, 0,
"/Udieresis", 0334, 0,
"/Yacute", 0335, 0,
"/Thorn", 0336, 0,
"/germandbls", 0337, 0,
"/agrave", 0340, 0,
"/aacute", 0341, 0,
"/acircumflex", 0342, 0,
"/atilde", 0343, 0,
"/adieresis", 0344, 0,
"/aring", 0345, 0,
"/ae", 0346, 0,
"/ccedilla", 0347, 0,
"/egrave", 0350, 0,
"/eacute", 0351, 0,
"/ecircumflex", 0352, 0,
"/edieresis", 0353, 0,
"/igrave", 0354, 0,
"/iacute", 0355, 0,
"/icircumflex", 0356, 0,
"/idieresis", 0357, 0,
"/eth", 0360, 0,
"/ntilde", 0361, 0,
"/ograve", 0362, 0,
"/oacute", 0363, 0,
"/ocircumflex", 0364, 0,
"/otilde", 0365, 0,
"/odieresis", 0366, 0,
"/divide", 0367, 0,
"/oslash", 0370, 0,
"/ugrave", 0371, 0,
"/uacute", 0372, 0,
"/ucircumflex", 0373, 0,
"/udieresis", 0374, 0,
"/yacute", 0375, 0,
"/thorn", 0376, 0,
"/ydieresis", 0377, 0
};
pschar scharlist[NSYMBL] = {
"/space", 040, 0,
"/exclam", 041, 0,
"/universal", 042, 0,
"/numbersign", 043, 0,
"/existential", 044, 0,
"/percent", 045, 0,
"/ampersand", 046, 0,
"/suchthat", 047, 0,
"/parenleft", 050, 0,
"/parenright", 051, 0,
"/asteriskmath", 052, 0,
"/plus", 053, 0,
"/comma", 054, 0,
"/minus", 055, 0,
"/period", 056, 0,
"/slash", 057, 0,
"/zero", 060, 0,
"/one", 061, 0,
"/two", 062, 0,
"/three", 063, 0,
"/four", 064, 0,
"/five", 065, 0,
"/six", 066, 0,
"/seven", 067, 0,
"/eight", 070, 0,
"/nine", 071, 0,
"/colon", 072, 0,
"/semicolon", 073, 0,
"/less", 074, 0,
"/equal", 075, 0,
"/greater", 076, 0,
"/question", 077, 0,
"/congruent", 0100, 0,
"/Alpha", 0101, 0,
"/Beta", 0102, 0,
"/Chi", 0103, 0,
"/Delta", 0104, 0,
"/Epsilon", 0105, 0,
"/Phi", 0106, 0,
"/Gamma", 0107, 0,
"/Eta", 0110, 0,
"/Iota", 0111, 0,
"/theta1", 0112, 0,
"/Kappa", 0113, 0,
"/Lambda", 0114, 0,
"/Mu", 0115, 0,
"/Nu", 0116, 0,
"/Omicron", 0117, 0,
"/Pi", 0120, 0,
"/Theta", 0121, 0,
"/Rho", 0122, 0,
"/Sigma", 0123, 0,
"/Tau", 0124, 0,
"/Upsilon", 0125, 0,
"/sigma1", 0126, 0,
"/Omega", 0127, 0,
"/Xi", 0130, 0,
"/Psi", 0131, 0,
"/Zeta", 0132, 0,
"/bracketleft", 0133, 0,
"/therefore", 0134, 0,
"/bracketright", 0135, 0,
"/perpendicular", 0136, 0,
"/underscore", 0137, 0,
"/radicalex", 0140, 0,
"/alpha", 0141, 0,
"/beta", 0142, 0,
"/chi", 0143, 0,
"/delta", 0144, 0,
"/epsilon", 0145, 0,
"/phi", 0146, 0,
"/gamma", 0147, 0,
"/eta", 0150, 0,
"/iota", 0151, 0,
"/phi1", 0152, 0,
"/kappa", 0153, 0,
"/lambda", 0154, 0,
"/mu", 0155, 0,
"/nu", 0156, 0,
"/omicron", 0157, 0,
"/pi", 0160, 0,
"/theta", 0161, 0,
"/rho", 0162, 0,
"/sigma", 0163, 0,
"/tau", 0164, 0,
"/upsilon", 0165, 0,
"/omega1", 0166, 0,
"/omega", 0167, 0,
"/xi", 0170, 0,
"/psi", 0171, 0,
"/zeta", 0172, 0,
"/braceleft", 0173, 0,
"/bar", 0174, 0,
"/braceright", 0175, 0,
"/similar", 0176, 0,
NULL, 0177, 0,
NULL, 0200, 0,
NULL, 0201, 0,
NULL, 0202, 0,
NULL, 0203, 0,
NULL, 0204, 0,
NULL, 0205, 0,
NULL, 0206, 0,
NULL, 0207, 0,
NULL, 0210, 0,
NULL, 0211, 0,
NULL, 0212, 0,
NULL, 0213, 0,
NULL, 0214, 0,
NULL, 0215, 0,
NULL, 0216, 0,
NULL, 0217, 0,
NULL, 0220, 0,
NULL, 0221, 0,
NULL, 0222, 0,
NULL, 0223, 0,
NULL, 0224, 0,
NULL, 0225, 0,
NULL, 0226, 0,
NULL, 0227, 0,
NULL, 0230, 0,
NULL, 0231, 0,
NULL, 0232, 0,
NULL, 0233, 0,
NULL, 0234, 0,
NULL, 0235, 0,
NULL, 0236, 0,
NULL, 0237, 0,
NULL, 0240, 0,
"/Upsilon1", 0241, 0,
"/minute", 0242, 0,
"/lessequal", 0243, 0,
"/fraction", 0244, 0,
"/infinity", 0245, 0,
"/florin", 0246, 0,
"/club", 0247, 0,
"/diamond", 0250, 0,
"/heart", 0251, 0,
"/spade", 0252, 0,
"/arrowboth", 0253, 0,
"/arrowleft", 0254, 0,
"/arrowup", 0255, 0,
"/arrowright", 0256, 0,
"/arrowdown", 0257, 0,
"/degree", 0260, 0,
"/plusminus", 0261, 0,
"/second", 0262, 0,
"/greaterequal", 0263, 0,
"/multiply", 0264, 0,
"/proportional", 0265, 0,
"/partialdiff", 0266, 0,
"/bullet", 0267, 0,
"/divide", 0270, 0,
"/notequal", 0271, 0,
"/equivalence", 0272, 0,
"/approxequal", 0273, 0,
"/ellipsis", 0274, 0,
"/arrowvertex", 0275, 0,
"/arrowhorizex", 0276, 0,
"/carriagereturn", 0277, 0,
"/aleph", 0300, 0,
"/Ifraktur", 0301, 0,
"/Rfraktur", 0302, 0,
"/weierstrass", 0303, 0,
"/circlemultiply", 0304, 0,
"/circleplus", 0305, 0,
"/emptyset", 0306, 0,
"/intersection", 0307, 0,
"/union", 0310, 0,
"/propersuperset", 0311, 0,
"/reflexsuperset", 0312, 0,
"/notsubset", 0313, 0,
"/propersubset", 0314, 0,
"/reflexsubset", 0315, 0,
"/element", 0316, 0,
"/notelement", 0317, 0,
"/angle", 0320, 0,
"/gradient", 0321, 0,
"/registerserif", 0322, 0,
"/copyrightserif", 0323, 0,
"/trademarkserif", 0324, 0,
"/product", 0325, 0,
"/radical", 0326, 0,
"/dotmath", 0327, 0,
"/logicalnot", 0330, 0,
"/logicaland", 0331, 0,
"/logicalor", 0332, 0,
"/arrowdblboth", 0333, 0,
"/arrowdblleft", 0334, 0,
"/arrowdblup", 0335, 0,
"/arrowdblright", 0336, 0,
"/arrowdbldown", 0337, 0,
"/lozenge", 0340, 0,
"/angleleft", 0341, 0,
"/registersans", 0342, 0,
"/copyrightsans", 0343, 0,
"/trademarksans", 0344, 0,
"/summation", 0345, 0,
"/parenlefttp", 0346, 0,
"/parenleftex", 0347, 0,
"/parenleftbt", 0350, 0,
"/bracketlefttp", 0351, 0,
"/bracketleftex", 0352, 0,
"/bracketleftbt", 0353, 0,
"/bracelefttp", 0354, 0,
"/braceleftmid", 0355, 0,
"/braceleftbt", 0356, 0,
"/braceex", 0357, 0,
"/apple", 0360, 0,
"/angleright", 0361, 0,
"/integral", 0362, 0,
"/integraltp", 0363, 0,
"/integralex", 0364, 0,
"/integralbt", 0365, 0,
"/parenrighttp", 0366, 0,
"/parenrightex", 0367, 0,
"/parenrightbt", 0370, 0,
"/bracketrighttp", 0371, 0,
"/bracketrightex", 0372, 0,
"/bracketrightbt", 0373, 0,
"/bracerighttp", 0374, 0,
"/bracerightmid", 0375, 0,
"/bracerightbt", 0376, 0,
NULL, 0377, 0
};
pschar zcharlist[NZAPFD] = {
"/space", 040, 0,
"/a1", 041, 0,
"/a2", 042, 0,
"/a202", 043, 0,
"/a3", 044, 0,
"/a4", 045, 0,
"/a5", 046, 0,
"/a119", 047, 0,
"/a118", 050, 0,
"/a117", 051, 0,
"/a11", 052, 0,
"/a12", 053, 0,
"/a13", 054, 0,
"/a14", 055, 0,
"/a15", 056, 0,
"/a16", 057, 0,
"/a105", 060, 0,
"/a17", 061, 0,
"/a18", 062, 0,
"/a19", 063, 0,
"/a20", 064, 0,
"/a21", 065, 0,
"/a22", 066, 0,
"/a23", 067, 0,
"/a24", 070, 0,
"/a25", 071, 0,
"/a26", 072, 0,
"/a27", 073, 0,
"/a28", 074, 0,
"/a6", 075, 0,
"/a7", 076, 0,
"/a8", 077, 0,
"/a9", 0100, 0,
"/a10", 0101, 0,
"/a29", 0102, 0,
"/a30", 0103, 0,
"/a31", 0104, 0,
"/a32", 0105, 0,
"/a33", 0106, 0,
"/a34", 0107, 0,
"/a35", 0110, 0,
"/a36", 0111, 0,
"/a37", 0112, 0,
"/a38", 0113, 0,
"/a39", 0114, 0,
"/a40", 0115, 0,
"/a41", 0116, 0,
"/a42", 0117, 0,
"/a43", 0120, 0,
"/a44", 0121, 0,
"/a45", 0122, 0,
"/a46", 0123, 0,
"/a47", 0124, 0,
"/a48", 0125, 0,
"/a49", 0126, 0,
"/a50", 0127, 0,
"/a51", 0130, 0,
"/a52", 0131, 0,
"/a53", 0132, 0,
"/a54", 0133, 0,
"/a55", 0134, 0,
"/a56", 0135, 0,
"/a57", 0136, 0,
"/a58", 0137, 0,
"/a59", 0140, 0,
"/a60", 0141, 0,
"/a61", 0142, 0,
"/a62", 0143, 0,
"/a63", 0144, 0,
"/a64", 0145, 0,
"/a65", 0146, 0,
"/a66", 0147, 0,
"/a67", 0150, 0,
"/a68", 0151, 0,
"/a69", 0152, 0,
"/a70", 0153, 0,
"/a71", 0154, 0,
"/a72", 0155, 0,
"/a73", 0156, 0,
"/a74", 0157, 0,
"/a203", 0160, 0,
"/a75", 0161, 0,
"/a204", 0162, 0,
"/a76", 0163, 0,
"/a77", 0164, 0,
"/a78", 0165, 0,
"/a79", 0166, 0,
"/a81", 0167, 0,
"/a82", 0170, 0,
"/a83", 0171, 0,
"/a84", 0172, 0,
"/a97", 0173, 0,
"/a98", 0174, 0,
"/a99", 0175, 0,
"/a100", 0176, 0,
NULL, 0177, 0,
NULL, 0200, 0,
NULL, 0201, 0,
NULL, 0202, 0,
NULL, 0203, 0,
NULL, 0204, 0,
NULL, 0205, 0,
NULL, 0206, 0,
NULL, 0207, 0,
NULL, 0210, 0,
NULL, 0211, 0,
NULL, 0212, 0,
NULL, 0213, 0,
NULL, 0214, 0,
NULL, 0215, 0,
NULL, 0216, 0,
NULL, 0217, 0,
NULL, 0220, 0,
NULL, 0221, 0,
NULL, 0222, 0,
NULL, 0223, 0,
NULL, 0224, 0,
NULL, 0225, 0,
NULL, 0226, 0,
NULL, 0227, 0,
NULL, 0230, 0,
NULL, 0231, 0,
NULL, 0232, 0,
NULL, 0233, 0,
NULL, 0234, 0,
NULL, 0235, 0,
NULL, 0236, 0,
NULL, 0237, 0,
NULL, 0240, 0,
"/a101", 0241, 0,
"/a102", 0242, 0,
"/a103", 0243, 0,
"/a104", 0244, 0,
"/a106", 0245, 0,
"/a107", 0246, 0,
"/a108", 0247, 0,
"/a112", 0250, 0,
"/a111", 0251, 0,
"/a110", 0252, 0,
"/a109", 0253, 0,
"/a120", 0254, 0,
"/a121", 0255, 0,
"/a122", 0256, 0,
"/a123", 0257, 0,
"/a124", 0260, 0,
"/a125", 0261, 0,
"/a126", 0262, 0,
"/a127", 0263, 0,
"/a128", 0264, 0,
"/a129", 0265, 0,
"/a130", 0266, 0,
"/a131", 0267, 0,
"/a132", 0270, 0,
"/a133", 0271, 0,
"/a134", 0272, 0,
"/a135", 0273, 0,
"/a136", 0274, 0,
"/a137", 0275, 0,
"/a138", 0276, 0,
"/a139", 0277, 0,
"/a140", 0300, 0,
"/a141", 0301, 0,
"/a142", 0302, 0,
"/a143", 0303, 0,
"/a144", 0304, 0,
"/a145", 0305, 0,
"/a146", 0306, 0,
"/a147", 0307, 0,
"/a148", 0310, 0,
"/a149", 0311, 0,
"/a150", 0312, 0,
"/a151", 0313, 0,
"/a152", 0314, 0,
"/a153", 0315, 0,
"/a154", 0316, 0,
"/a155", 0317, 0,
"/a156", 0320, 0,
"/a157", 0321, 0,
"/a158", 0322, 0,
"/a159", 0323, 0,
"/a160", 0324, 0,
"/a161", 0325, 0,
"/a163", 0326, 0,
"/a164", 0327, 0,
"/a196", 0330, 0,
"/a165", 0331, 0,
"/a192", 0332, 0,
"/a166", 0333, 0,
"/a167", 0334, 0,
"/a168", 0335, 0,
"/a169", 0336, 0,
"/a170", 0337, 0,
"/a171", 0340, 0,
"/a172", 0341, 0,
"/a173", 0342, 0,
"/a162", 0343, 0,
"/a174", 0344, 0,
"/a175", 0345, 0,
"/a176", 0346, 0,
"/a177", 0347, 0,
"/a178", 0350, 0,
"/a179", 0351, 0,
"/a193", 0352, 0,
"/a180", 0353, 0,
"/a199", 0354, 0,
"/a181", 0355, 0,
"/a200", 0356, 0,
"/a182", 0357, 0,
NULL, 0360, 0,
"/a201", 0361, 0,
"/a183", 0362, 0,
"/a184", 0363, 0,
"/a197", 0364, 0,
"/a185", 0365, 0,
"/a194", 0366, 0,
"/a198", 0367, 0,
"/a186", 0370, 0,
"/a195", 0371, 0,
"/a187", 0372, 0,
"/a188", 0373, 0,
"/a189", 0374, 0,
"/a190", 0375, 0,
"/a191", 0376, 0,
NULL, 0377, 0
};
static int dopoints;
fntpointmode(size)
int size;
{
dopoints = size;
}
/*
* printing stuff for debugging
*
*
*/
printobjfnt(fnt)
objfnt *fnt;
{
int i;
printf("Object font type is %d\n",fnt->type);
printf("First char is %d\n",fnt->charmin);
printf("Last char is %d\n",fnt->charmax);
printf("Num chars is %d\n",fnt->nchars);
printf("Fnt scale is %d\n\n",fnt->scale);
for(i=fnt->charmin; i<=fnt->charmax; i++)
printobjchar(fnt,i);
}
short *getcharprog(fnt,c)
objfnt *fnt;
int c;
{
int index;
chardesc *cd;
index = chartoindex(fnt,c);
if(index<0)
return 0;
cd = fnt->chars+index;
return cd->data;
}
chardesc *getchardesc(fnt,c)
objfnt *fnt;
int c;
{
int index;
index = chartoindex(fnt,c);
if(index<0)
return 0;
return fnt->chars+index;
}
int chartoindex(fnt,c)
objfnt *fnt;
int c;
{
if(c<fnt->charmin)
return -1;
if(c>fnt->charmax)
return -1;
return c-fnt->charmin;
}
printobjchar(fnt,c)
objfnt *fnt;
int c;
{
int index;
chardesc *cd;
index = chartoindex(fnt,c);
if(index<0)
return 0;
cd = fnt->chars+index;
printf("Char '%c' code is %d\n",c,c);
printf("Advance %d %d\n",cd->movex,cd->movey);
printf("Bbox %d %d to %d %d\n",cd->llx,cd->lly,cd->urx,cd->ury);
printf("Data %d tokens\n\n",cd->datalen/2);
if(cd->data) {
switch(fnt->type) {
case PO_TYPE:
poly_print(cd->data);
break;
case SP_TYPE:
spline_print(cd->data);
break;
case TM_TYPE:
fprintf(stderr,"printobjchar: can't print meshed fonts yet\n");
break;
default:
fprintf(stderr,"printobjchar: bad obj font type\n");
}
}
return 1;
}
applytoobjfntverts(fnt,func)
objfnt *fnt;
int (*func)();
{
int c;
for(c=fnt->charmin; c<=fnt->charmax; c++)
applytocharverts(fnt,c,func);
}
applytocharverts(fnt,c,func)
objfnt *fnt;
int c;
int (*func)();
{
int index;
chardesc *cd;
short *sptr;
int nverts;
index = chartoindex(fnt,c);
if(index<0)
return;
cd = fnt->chars+index;
if(cd->data) {
sptr = cd->data;
switch(fnt->type) {
case TM_TYPE:
while(1) {
switch(*sptr++) {
case TM_BGNTMESH:
case TM_SWAPTMESH:
case TM_ENDBGNTMESH:
break;
case TM_RETENDTMESH:
case TM_RET:
return;
default:
fprintf(stderr,"applytocharverts: bad TM op\n");
return;
}
nverts = *sptr++;
while(nverts--) {
(func)(sptr);
sptr+=2;
}
}
break;
case PO_TYPE:
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
case PO_ENDBGNLOOP:
break;
case PO_RETENDLOOP:
case PO_RET:
return;
break;
default:
fprintf(stderr,"applytocharverts: bad PO op\n");
return;
}
nverts = *sptr++;
while(nverts--) {
(func)(sptr);
sptr+=2;
}
}
break;
case SP_TYPE:
while(1) {
switch(*sptr++) {
case SP_MOVETO:
(func)(sptr);
sptr+=2;
break;
case SP_LINETO:
(func)(sptr);
sptr+=2;
break;
case SP_CURVETO:
(func)(sptr+0);
(func)(sptr+2);
(func)(sptr+4);
sptr+=6;
break;
case SP_CLOSEPATH:
break;
case SP_RETCLOSEPATH:
return;
break;
case SP_RET:
return;
break;
default:
fprintf(stderr,"applytocharverts: bad SP op\n");
return;
}
}
break;
default:
fprintf(stderr,"applytocharverts: bad obj font type\n");
}
}
}
applytocharedges(fnt,c,func)
objfnt *fnt;
int c;
int (*func)();
{
int i, index, nverts;
chardesc *cd;
short *sptr, *p1, *p2;
if(fnt->type != PO_TYPE) {
fprintf(stderr,"applytocharedges only works on PO_TYPE fonts\n");
exit(1);
}
index = chartoindex(fnt,c);
if(index<0)
return;
cd = fnt->chars+index;
if(cd->data) {
sptr = cd->data;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
case PO_ENDBGNLOOP:
break;
case PO_RETENDLOOP:
case PO_RET:
return;
}
nverts = *sptr++;
for(i=0; i<nverts; i++) {
p1 = sptr+(2*(i));
p2 = sptr+(2*((i+1)%nverts));
(func)(p1,p2);
}
sptr+=(2*nverts);
}
}
}
static int xmin, xmax, ymin, ymax;
static bboxcalc(v)
short v[2];
{
if(v[0]<xmin)
xmin = v[0];
if(v[1]<ymin)
ymin = v[1];
if(v[0]>xmax)
xmax = v[0];
if(v[1]>ymax)
ymax = v[1];
}
fontbbox(fnt,llx,lly,urx,ury)
objfnt *fnt;
int *llx, *lly, *urx, *ury;
{
xmin = ymin = NOBBOX;
xmax = ymax = -NOBBOX;
applytoobjfntverts(fnt,bboxcalc);
if(xmin == NOBBOX) {
*llx = NOBBOX;
*lly = NOBBOX;
*urx = NOBBOX;
*ury = NOBBOX;
} else {
*llx = xmin;
*lly = ymin;
*urx = xmax;
*ury = ymax;
}
}
calccharbboxes(fnt)
objfnt *fnt;
{
int c;
chardesc *cd;
for(c=fnt->charmin; c<=fnt->charmax; c++) {
xmin = ymin = NOBBOX;
xmax = ymax = -NOBBOX;
applytocharverts(fnt,c,bboxcalc);
cd = getchardesc(fnt,c);
if(xmin == NOBBOX) {
cd->llx = NOBBOX;
cd->lly = NOBBOX;
cd->urx = NOBBOX;
cd->ury = NOBBOX;
} else {
cd->llx = xmin;
cd->lly = ymin;
cd->urx = xmax;
cd->ury = ymax;
}
}
}
/*
* poly_print -
* Print a poly character
*
*/
static poly_print(sptr)
short *sptr;
{
int nverts;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
printf("bgnloop\n");
break;
case PO_ENDBGNLOOP:
printf("endbgnloop\n\n");
break;
case PO_RETENDLOOP:
printf("retendloop\n\n");
return;
break;
case PO_RET:
printf("ret\n\n");
return;
break;
default:
fprintf(stderr,"poly_print: bad PO op\n");
return;
}
nverts = *sptr++;
while(nverts--) {
printf(" vert %d %d\n",sptr[0],sptr[1]);
sptr+=2;
}
}
}
/*
* spline_print -
* Print a spline character
*
*/
static spline_print(sptr)
short *sptr;
{
int nverts;
while(1) {
switch(*sptr++) {
case SP_MOVETO:
printf("beginloop\n");
printf(" moveto %d %d\n",sptr[0], sptr[1]);
sptr+=2;
break;
case SP_LINETO:
printf(" lineto %d %d\n",sptr[0], sptr[1]);
sptr+=2;
break;
case SP_CURVETO:
printf(" curveto %d %d %d %d %d %d\n",
sptr[0],sptr[1],sptr[2],sptr[3],sptr[4],sptr[5]);
sptr+=6;
break;
case SP_CLOSEPATH:
printf("endloop\n");
break;
case SP_RETCLOSEPATH:
printf("endloop\n");
printf("ret\n\n");
return;
break;
case SP_RET:
printf("ret\n\n");
return;
break;
default:
fprintf(stderr,"spline_print: bad SP op\n");
return;
}
}
}
/*
* tmesh_draw -
* Draw a tmesh character
*
*/
static tmesh_draw(sptr)
short *sptr;
{
int nverts;
while(1) {
switch(*sptr++) {
case TM_BGNTMESH:
bgntmesh();
break;
case TM_SWAPTMESH:
swaptmesh();
break;
case TM_ENDBGNTMESH:
endtmesh();
bgntmesh();
break;
case TM_RETENDTMESH:
endtmesh();
return;
case TM_RET:
endtmesh();
return;
default:
fprintf(stderr,"tmesh_draw: bad TM op\n");
return;
}
nverts = *sptr++;
while(nverts--) {
v2s(sptr);
sptr+=2;
}
}
}
/*
* point_draw -
* Draw the points in a character.
*
*/
static point_draw(sptr,size)
short *sptr;
int size;
{
int nverts, vertno;
int x, y, del;
del = size/2;
if(del == 0)
del = 1;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
break;
case PO_ENDBGNLOOP:
break;
case PO_RETENDLOOP:
return;
break;
case PO_RET:
return;
break;
default:
fprintf(stderr,"point_draw: bad PO op\n");
return;
}
nverts = *sptr++;
vertno = 1;
while(nverts--) {
x = sptr[0];
y = sptr[1];
if(vertno++ == 1)
cpack(0x008000);
else
cpack(0x0000ff);
if(size == 1)
pnt2i(x,y);
else
rectfi(x-del,y-del,x+del,y+del);
sptr+=2;
}
}
}
/*
* poly_draw -
* Draw a poly character
*
*/
static poly_draw(sptr)
short *sptr;
{
int nverts;
while(1) {
switch(*sptr++) {
case PO_BGNLOOP:
bgnclosedline();
break;
case PO_ENDBGNLOOP:
endclosedline();
bgnclosedline();
break;
case PO_RETENDLOOP:
endclosedline();
return;
break;
case PO_RET:
return;
break;
default:
fprintf(stderr,"poly_draw: bad PO op\n");
return;
}
nverts = *sptr++;
while(nverts--) {
v2s(sptr);
sptr+=2;
}
}
}
/*
* spline_draw -
* Draw a spline character
*
*/
static spline_draw(sptr)
short *sptr;
{
while(1) {
switch(*sptr++) {
case SP_MOVETO:
bgnclosedline();
v2s(sptr);
sptr+=2;
break;
case SP_LINETO:
v2s(sptr);
sptr+=2;
break;
case SP_CURVETO:
drawcurve(sptr-3,sptr,sptr+2,sptr+4);
sptr+=6;
break;
case SP_CLOSEPATH:
endclosedline();
break;
case SP_RETCLOSEPATH:
endclosedline();
return;
break;
case SP_RET:
return;
break;
default:
fprintf(stderr,"spline_draw: bad SP op\n");
return;
}
}
}
#define BEZTOL 2.0
static drawcurve(v0,v1,v2,v3)
short v0[2], v1[2], v2[2], v3[2];
{
float x0, y0, x1, y1, x2, y2, x3, y3;
x0 = v0[0];
y0 = v0[1];
x1 = v1[0];
y1 = v1[1];
x2 = v2[0];
y2 = v2[1];
x3 = v3[0];
y3 = v3[1];
bezadapt(x0,y0,x1,y1,x2,y2,x3,y3,BEZTOL);
}
static bezadapt(x0,y0,x1,y1,x2,y2,x3,y3,beztol)
float x0,y0,x1,y1,x2,y2,x3,y3;
float beztol;
{
float ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3;
float bx0,by0,bx1,by1,bx2,by2,bx3,by3;
float midx, midy;
float linx, liny, dx, dy, mag;
float v[2];
midx = (x0+3*x1+3*x2+x3)/8.0;
midy = (y0+3*y1+3*y2+y3)/8.0;
linx = (x0+x3)/2.0;
liny = (y0+y3)/2.0;
dx = midx-linx;
dy = midy-liny;
mag = dx*dx+dy*dy;
if(mag<(beztol*beztol)) {
v[0] = x3;
v[1] = y3;
v2f(v);
} else {
ax0 = x0;
ay0 = y0;
ax1 = (x0+x1)/2;
ay1 = (y0+y1)/2;
ax2 = (x0+2*x1+x2)/4;
ay2 = (y0+2*y1+y2)/4;
ax3 = midx;
ay3 = midy;
bezadapt(ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3,beztol);
bx0 = midx;
by0 = midy;
bx1 = (x1+2*x2+x3)/4;
by1 = (y1+2*y2+y3)/4;
bx2 = (x2+x3)/2;
by2 = (y2+y3)/2;
bx3 = x3;
by3 = y3;
bezadapt(bx0,by0,bx1,by1,bx2,by2,bx3,by3,beztol);
}
}
objfnt *readobjfnt(name)
char *name;
{
FILE *inf;
objfnt *fnt;
short *sptr;
int i;
long magic;
inf = res_fopen(name,"r");
if(!inf) {
fprintf(stderr,"readobjfnt: can't open input file %s\n",name);
return 0;
}
res_fread(&magic,sizeof(long),1,inf);
if(magic != OFMAGIC) {
fprintf(stderr,"readobjfnt: bad magic nuber\n");
return 0;
}
fnt = (objfnt *)mymalloc(sizeof(objfnt));
res_fread(fnt,sizeof(objfnt),1,inf);
fnt->freeaddr = 0;
fnt->chars = (chardesc *)mymalloc(fnt->nchars*sizeof(chardesc));
res_fread(fnt->chars,fnt->nchars*sizeof(chardesc),1,inf);
for(i=0; i<fnt->nchars; i++) {
if(fnt->chars[i].datalen>0) {
sptr = (short *)mymalloc(fnt->chars[i].datalen);
fnt->chars[i].data = sptr;
fread(sptr,fnt->chars[i].datalen,1,inf);
} else {
fnt->chars[i].data = 0;
}
}
res_fclose(inf);
return fnt;
}
writeobjfnt(name,fnt)
char *name;
objfnt *fnt;
{
FILE *of;
int i;
long magic;
calccharbboxes(fnt);
of = fopen(name,"w");
if(!of) {
fprintf(stderr,"writeobjfnt: can't open output file %s\n",name);
return 0;
}
magic = OFMAGIC;
fwrite(&magic,sizeof(long),1,of);
fwrite(fnt,sizeof(objfnt),1,of);
fwrite(fnt->chars,fnt->nchars*sizeof(chardesc),1,of);
for(i=0; i<fnt->nchars; i++) {
if(fnt->chars[i].datalen>0)
fwrite(fnt->chars[i].data,fnt->chars[i].datalen,1,of);
}
fclose(of);
}
objfnt *newobjfnt(type,charmin,charmax,fscale)
int type, charmin, charmax, fscale;
{
objfnt *fnt;
short *sptr;
int i;
fnt = (objfnt *)mymalloc(sizeof(objfnt));
fnt->freeaddr = 0;
fnt->type = type;
fnt->charmin = charmin;
fnt->charmax = charmax;
fnt->nchars = fnt->charmax-fnt->charmin+1;
fnt->scale = fscale;
fnt->chars = (chardesc *)mymalloc(fnt->nchars*sizeof(chardesc));
bzero(fnt->chars,fnt->nchars*sizeof(chardesc));
return fnt;
}
freeobjfnt(fnt)
objfnt *fnt;
{
int i;
chardesc *cd;
cd = fnt->chars;
for(i=0; i<fnt->nchars; i++) {
if(cd->data)
free(cd->data);
cd++;
}
free(fnt->chars);
free(fnt);
}
addchardata(fnt,c,data,nshorts)
objfnt *fnt;
int c;
short *data;
int nshorts;
{
int index;
chardesc *cd;
index = chartoindex(fnt,c);
if(index<0) {
fprintf(stderr,"Addchardata bad poop\n");
return;
}
cd = fnt->chars+index;
fnt->freeaddr = 0;
cd->datalen = nshorts*sizeof(short);
cd->data = (short *)mymalloc(cd->datalen);
bcopy(data,cd->data,cd->datalen);
}
addcharmetrics(fnt,c,movex,movey)
objfnt *fnt;
int c;
int movex, movey;
{
int index;
chardesc *cd;
index = chartoindex(fnt,c);
if(index<0) {
fprintf(stderr,"Addcharmetrics bad poop\n");
return;
}
cd = fnt->chars+index;
cd->movex = movex;
cd->movey = movey;
}
drawobjchar(fnt,c)
objfnt *fnt;
int c;
{
chardesc *cd;
cd = getchardesc(fnt,c);
if(!cd)
return 0;
if(cd->data) {
switch(fnt->type) {
case TM_TYPE:
tmesh_draw(cd->data);
break;
case PO_TYPE:
if(dopoints)
point_draw(cd->data,dopoints);
else
poly_draw(cd->data);
break;
case SP_TYPE:
spline_draw(cd->data);
break;
default:
fprintf(stderr,"drawobjchar: bad obj font type\n");
}
}
translate((float)cd->movex,(float)cd->movey,0.0);
return 1;
}
drawobjcharbbox(fnt,c)
objfnt *fnt;
int c;
{
chardesc *cd;
cd = getchardesc(fnt,c);
if(!cd)
return 0;
if(cd->llx != NOBBOX)
drawrect((float)cd->llx,(float)cd->lly,(float)cd->urx,(float)cd->ury);
return 1;
}
getcharadvance(fnt,c,dx,dy)
objfnt *fnt;
int c, *dx, *dy;
{
int index;
chardesc *cd;
index = chartoindex(fnt,c);
if(index<0) {
*dx = 0;
*dy = 0;
return 0;
} else {
cd = fnt->chars+index;
*dx = cd->movex;
*dy = cd->movey;
return 1;
}
}
static float fontsize = 1.0;
static float xpos, ypos;
static int nfonts;
static char *names[40];
static objfnt *objfnts[40];
static objfnt *curfont;
fontsetsize(size)
float size;
{
fontsize = size;
}
fontmoveto(x,y)
float x, y;
{
xpos = x;
ypos = y;
}
fontrmoveto(x,y)
float x, y;
{
xpos += x;
ypos += y;
}
fontptr(fnt)
objfnt *fnt;
{
curfont = fnt;
}
objfnt *fontname(name)
char *name;
{
objfnt *fnt;
int i;
for(i=0; i<nfonts; i++) {
if(strcmp(name,names[i]) == 0) {
curfont = objfnts[i];
return curfont;
}
}
if(nfonts==256) {
fprintf(stderr,"fontname: too many fonts\n",name);
return NULL;
}
fnt = readobjfnt(name);
if(!fnt) {
fprintf(stderr,"fontname: can't find font %s\n",name);
return NULL;
} else {
objfnts[nfonts] = fnt;
names[nfonts] = (char *)mymalloc(strlen(name)+1);
bcopy(name,names[nfonts],strlen(name)+1);
nfonts++;
curfont = fnt;
return curfont;
}
}
fontpurge(name)
char *name;
{
int i, k;
for(i=0; i<nfonts; i++) {
if(strcmp(name,names[i]) == 0) {
if (curfont == objfnts[i]) {
if (nfonts > 0)
curfont = objfnts[0];
else
curfont = NULL;
}
free (objfnts[i]); /* XXXX */
free (names[i]);
for (k = i; k < nfonts - 1; k++) {
objfnts[k] = objfnts[k+1];
names[k] = names[k+1];
}
nfonts--;
return;
}
}
fprintf (stderr, "fontfree: couldn't find font %s to delete!\n", name);
}
float fontstringwidth(str)
unsigned char *str;
{
int width, w, dy;
width = 0;
while(*str) {
getcharadvance(curfont,*str,&w,&dy);
str++;
width += w;
}
return width*fontsize/curfont->scale;
}
fontshow(str)
unsigned char *str;
{
int n, onechar;
pushmatrix();
translate(xpos,ypos,0.0);
xpos += fontstringwidth(str);
scale(fontsize/curfont->scale,fontsize/curfont->scale,0.0);
n = 0;
while(*str) {
n += drawobjchar(curfont,*str);
str++;
}
popmatrix();
return n;
}
bboxshow(str)
unsigned char *str;
{
int n, onechar;
pushmatrix();
translate(xpos,ypos,0.0);
xpos += fontstringwidth(str);
scale(fontsize/curfont->scale,fontsize/curfont->scale,0.0);
n = 0;
while(*str) {
n += drawobjcharbbox(curfont,*str);
str++;
}
popmatrix();
return n;
}
char *asciiname(c)
char c;
{
if((c>=MIN_ASCII) && (c<=MAX_ASCII))
return charlist[c-MIN_ASCII].name+1;
else
return 0;
}
hasvertdata(fnt,c)
objfnt *fnt;
int c;
{
chardesc *cd;
cd = getchardesc(fnt,c);
if(cd->llx == NOBBOX)
return 0;
else
return 1;
}
fontcentershow(str)
char *str;
{
float width;
width = fontstringwidth(str);
fontrmoveto(-width/2.0,0.0);
fontshow(str);
}
fakechar(fnt,c,width)
objfnt *fnt;
int c, width;
{
short chardata[1];
chardata[0] = PO_RET;
addchardata(fnt,c,chardata,1);
addcharmetrics(fnt,c,width,0);
}
mergefont(dest,src)
objfnt *dest, *src;
{
int c;
chardesc *dcd, *scd;
for(c=dest->charmin; c<=dest->charmax; c++) {
if(charexists(src,c)) {
dcd = getchardesc(dest,c);
scd = getchardesc(src,c);
dcd->movex = scd->movex;
dcd->movey = scd->movey;
dcd->llx = scd->llx;
dcd->lly = scd->lly;
dcd->urx = scd->urx;
dcd->ury = scd->ury;
dcd->datalen = scd->datalen;
dcd->data = (short *)mymalloc(dcd->datalen);
bcopy(scd->data,dcd->data,dcd->datalen);
}
}
}
charexists(fnt,c)
objfnt *fnt;
int c;
{
chardesc *cd;
cd=getchardesc(fnt,c);
if(!cd)
return 0;
else if(cd->data)
return 1;
else
return 0;
}